{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "![](https://raw.githubusercontent.com/Qinbf/tf-model-zoo/master/README_IMG/01.jpg)\n",
    "AI MOOC： **www.ai-xlab.com**  \n",
    "如果你也是AI爱好者，可以添加我的微信一起交流：**sdxxqbf**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 载入数据\n",
    "data = np.genfromtxt(\"kmeans.txt\", delimiter=\" \")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算距离 \n",
    "def euclDistance(vector1, vector2):  \n",
    "    return np.sqrt(sum((vector2 - vector1)**2))\n",
    "  \n",
    "# 初始化质心\n",
    "def initCentroids(data, k):  \n",
    "    numSamples, dim = data.shape\n",
    "    # k个质心，列数跟样本的列数一样\n",
    "    centroids = np.zeros((k, dim))  \n",
    "    # 随机选出k个质心\n",
    "    for i in range(k):  \n",
    "        # 随机选取一个样本的索引\n",
    "        index = int(np.random.uniform(0, numSamples))  \n",
    "        # 作为初始化的质心\n",
    "        centroids[i, :] = data[index, :]  \n",
    "    return centroids  \n",
    "  \n",
    "# 传入数据集和k的值\n",
    "def kmeans(data, k):  \n",
    "    # 计算样本个数\n",
    "    numSamples = data.shape[0]   \n",
    "    # 样本的属性，第一列保存该样本属于哪个簇，第二列保存该样本跟它所属簇的误差\n",
    "    clusterData = np.array(np.zeros((numSamples, 2)))  \n",
    "    # 决定质心是否要改变的变量\n",
    "    clusterChanged = True  \n",
    "  \n",
    "    # 初始化质心  \n",
    "    centroids = initCentroids(data, k)  \n",
    "  \n",
    "    while clusterChanged:  \n",
    "        clusterChanged = False  \n",
    "        # 循环每一个样本 \n",
    "        for i in range(numSamples):  \n",
    "            # 最小距离\n",
    "            minDist  = 100000.0  \n",
    "            # 定义样本所属的簇\n",
    "            minIndex = 0  \n",
    "            # 循环计算每一个质心与该样本的距离\n",
    "            for j in range(k):  \n",
    "                # 循环每一个质心和样本，计算距离\n",
    "                distance = euclDistance(centroids[j, :], data[i, :])  \n",
    "                # 如果计算的距离小于最小距离，则更新最小距离\n",
    "                if distance < minDist:  \n",
    "                    minDist  = distance  \n",
    "                    # 更新样本所属的簇\n",
    "                    minIndex = j  \n",
    "                    # 更新最小距离\n",
    "                    clusterData[i, 1] = distance\n",
    "              \n",
    "            # 如果样本的所属的簇发生了变化\n",
    "            if clusterData[i, 0] != minIndex:  \n",
    "                # 质心要重新计算\n",
    "                clusterChanged = True\n",
    "                # 更新样本的簇\n",
    "                clusterData[i, 0] = minIndex\n",
    "  \n",
    "        # 更新质心\n",
    "        for j in range(k):  \n",
    "            # 获取第j个簇所有的样本所在的索引\n",
    "            cluster_index = np.nonzero(clusterData[:, 0] == j)\n",
    "            # 第j个簇所有的样本点\n",
    "            pointsInCluster = data[cluster_index]  \n",
    "            # 计算质心\n",
    "            centroids[j, :] = np.mean(pointsInCluster, axis = 0) \n",
    "#         showCluster(data, k, centroids, clusterData)\n",
    "  \n",
    "    return centroids, clusterData  \n",
    "  \n",
    "# 显示结果 \n",
    "def showCluster(data, k, centroids, clusterData):  \n",
    "    numSamples, dim = data.shape  \n",
    "    if dim != 2:  \n",
    "        print(\"dimension of your data is not 2!\")  \n",
    "        return 1  \n",
    "  \n",
    "    # 用不同颜色形状来表示各个类别\n",
    "    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']  \n",
    "    if k > len(mark):  \n",
    "        print(\"Your k is too large!\")  \n",
    "        return 1  \n",
    "  \n",
    "    # 画样本点  \n",
    "    for i in range(numSamples):  \n",
    "        markIndex = int(clusterData[i, 0])  \n",
    "        plt.plot(data[i, 0], data[i, 1], mark[markIndex])  \n",
    "  \n",
    "    # 用不同颜色形状来表示各个类别\n",
    "    mark = ['*r', '*b', '*g', '*k', '^b', '+b', 'sb', 'db', '<b', 'pb']  \n",
    "    # 画质心点 \n",
    "    for i in range(k):  \n",
    "        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 20)  \n",
    "  \n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "F:\\Anaconda3\\lib\\site-packages\\numpy\\core\\fromnumeric.py:2957: RuntimeWarning: Mean of empty slice.\n",
      "  out=out, **kwargs)\n",
      "F:\\Anaconda3\\lib\\site-packages\\numpy\\core\\_methods.py:73: RuntimeWarning: invalid value encountered in true_divide\n",
      "  ret, rcount, out=ret, casting='unsafe', subok=False)\n"
     ]
    }
   ],
   "source": [
    "list_lost = []\n",
    "for k in range(2,10):\n",
    "    min_loss = 10000\n",
    "    min_loss_centroids = np.array([])\n",
    "    min_loss_clusterData = np.array([])\n",
    "    for i in range(50):\n",
    "        # centroids 簇的中心点 \n",
    "        # cluster Data样本的属性，第一列保存该样本属于哪个簇，第二列保存该样本跟它所属簇的误差\n",
    "        centroids, clusterData = kmeans(data, k)  \n",
    "        loss = sum(clusterData[:,1])/data.shape[0]\n",
    "        if loss < min_loss:\n",
    "            min_loss = loss\n",
    "            min_loss_centroids = centroids\n",
    "            min_loss_clusterData = clusterData\n",
    "    list_lost.append(min_loss)\n",
    "    \n",
    "#     print('loss',min_loss)\n",
    "# print('cluster complete!')      \n",
    "# centroids = min_loss_centroids\n",
    "# clusterData = min_loss_clusterData\n",
    "\n",
    "# 显示结果\n",
    "# showCluster(data, k, centroids, clusterData)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2.9811811738953176,\n",
       " 1.9708559728104191,\n",
       " 1.1675654672086735,\n",
       " 1.0712368269135584,\n",
       " 1.0076791550071307,\n",
       " 0.9486882361537872,\n",
       " 0.8894548052893553,\n",
       " 0.8360230313242516]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list_lost"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x22eb1ad7dd8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(range(2,10),list_lost)\n",
    "plt.xlabel('k')\n",
    "plt.ylabel('loss')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 做预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1],\n",
       "       [0, 1],\n",
       "       [0, 1],\n",
       "       [0, 1]])"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 做预测\n",
    "x_test = [0,1]\n",
    "np.tile(x_test,(k,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 3.53973889,  3.89384326],\n",
       "       [ 2.46154315, -1.78737555],\n",
       "       [-2.6265299 , -2.10868015],\n",
       "       [-2.65077367,  3.79019029]])"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差\n",
    "np.tile(x_test,(k,1))-centroids"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 12.52975144,  15.16201536],\n",
       "       [  6.05919468,   3.19471136],\n",
       "       [  6.89865932,   4.44653198],\n",
       "       [  7.02660103,  14.3655424 ]])"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差平方\n",
    "(np.tile(x_test,(k,1))-centroids)**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 27.6917668 ,   9.25390604,  11.34519129,  21.39214343])"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差平方和\n",
    "((np.tile(x_test,(k,1))-centroids)**2).sum(axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最小值所在的索引号\n",
    "np.argmin(((np.tile(x_test,(k,1))-centroids)**2).sum(axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(datas):\n",
    "    return np.array([np.argmin(((np.tile(data,(k,1))-centroids)**2).sum(axis=1)) for data in datas])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 画出簇的作用区域"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nF5oAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1bd9e1a9f60>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 获取数据值所在的范围\n",
    "x_min, x_max = data[:, 0].min() - 1, data[:, 0].max() + 1\n",
    "y_min, y_max = data[:, 1].min() - 1, data[:, 1].max() + 1\n",
    "\n",
    "# 生成网格矩阵\n",
    "xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),\n",
    "                     np.arange(y_min, y_max, 0.02))\n",
    "\n",
    "z = predict(np.c_[xx.ravel(), yy.ravel()])# ravel与flatten类似，多维数据转一维。flatten不会改变原始数据，ravel会改变原始数据\n",
    "z = z.reshape(xx.shape)\n",
    "# 等高线图\n",
    "cs = plt.contourf(xx, yy, z)\n",
    "# 显示结果\n",
    "showCluster(data, k, centroids, clusterData)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
